﻿package kr.pfg.applications.captureyourscreen.display
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import kr.as3.component.RollOverButton;
	import kr.as3.display.FadeLayer;
	import kr.as3.display.ResizeAlign;
	import kr.as3.display.ResizeHelper;
	import kr.as3.display.ResizeScale;
	import kr.pfg.applications.captureyourscreen.events.CaptureEvent;

	public class CaptureFrame extends Sprite
	{
		public var border: FadeLayer;
		public var resizeIcon: FadeLayer;
		public var resizeIconDummy: Sprite;
		public var btnCapture: RollOverButton;
		public var btnCaptureFull: RollOverButton;
		public var guideline:Sprite;
		
		private var _parent: DisplayObject
		
		public function CaptureFrame( $parent: DisplayObject )
		{
			this._parent = $parent;
			
			this.initDrag();
			this.initResize();
			this.initButtons();
		}
		
		private var dragBound: Rectangle;
		/**
		 * Dragging.
		 */
		private function initDrag(): void
		{
			this.border.buttonMode = true;
			this.border.addEventListener( MouseEvent.MOUSE_DOWN, dragStart );
			this.border.status = FadeLayer.SHOW;
			this.resizeIcon.status = FadeLayer.SHOW;
			this.resizeIcon.fadeOutAlpha = 0.3;
		}
		
		private function dragStart( e: Event ): void
		{
			this.dragBound = new Rectangle( 0, 0, this._parent.width - this.border.width, this._parent.height - this.border.height );
			
			this.startDrag( false, this.dragBound );
			
			this.stage.addEventListener( MouseEvent.MOUSE_UP, dragStop );
			this.stage.addEventListener( Event.MOUSE_LEAVE, dragStop );
			this.addEventListener( Event.ENTER_FRAME, dragEdgeHandler );
		}
		
		private const EDGE: int = 10;
		private var fading: Boolean = false;
		private function dragEdgeHandler( e: Event ): void
		{
			var bound: Rectangle = this.region;
			
			var currentFading: Boolean;
			
			if( bound.x < EDGE || bound.y < EDGE || this._parent.width - bound.width - bound.x < EDGE || this._parent.height - bound.height - bound.y < EDGE )
				currentFading = false;
			else
				currentFading = true;
				
			if( this.fading == currentFading )
				return;
				
			this.fading = currentFading;
			
			if( this.fading )
			{
				this.border.fadeIn();
				this.resizeIcon.fadeIn();
			}
			else
			{
				this.border.fadeOut();
				this.resizeIcon.fadeOut();
			}
		}
		
		private function dragStop( e: Event ): void
		{
			trace( "region :: ", this.region );
			this.removeEventListener( Event.ENTER_FRAME, dragEdgeHandler );
			this.stage.removeEventListener( MouseEvent.MOUSE_UP, dragStop );
			this.stage.removeEventListener( Event.MOUSE_LEAVE, dragStop );
			
			this.stopDrag();
		}
		
		private var resizeBound: Rectangle;
		private var resizeDummyMargin: Point;
		/**
		 * Resizing. 
		 */
		private function resizeStart( e: Event ): void
		{
			this.resizeIconDummy.startDrag( false, this.resizeBound );
			
			this.addEventListener( Event.ENTER_FRAME, resizeListener );
			this.stage.addEventListener( MouseEvent.MOUSE_UP, resizeStop );
			this.stage.addEventListener( Event.MOUSE_LEAVE, resizeStop );
			this.addEventListener( Event.ENTER_FRAME, dragEdgeHandler );
		}
		
		private function resizeListener( e: Event ): void
		{
			this.resizer.resize( this.resizeDummyMargin.x + this.resizeIconDummy.x, this.resizeDummyMargin.y + this.resizeIconDummy.y );
		}
		
		private function resizeStop( e: Event ): void
		{
			this.removeEventListener( Event.ENTER_FRAME, dragEdgeHandler );
			this.removeEventListener( Event.ENTER_FRAME, resizeListener );
			this.stage.removeEventListener( MouseEvent.MOUSE_UP, resizeStop );
			this.stage.removeEventListener( Event.MOUSE_LEAVE, resizeStop );
			
			this.resizeIconDummy.stopDrag();
		}
		
		private var resizer: ResizeHelper;
		/**
		 * Resize Helper
		 */
		private function initResize(): void
		{
			this.resizer = new ResizeHelper( this, true );
			this.resizer.addScale( this.border, ResizeScale.XY );
			this.resizer.addPosition( this.resizeIcon, ResizeAlign.RIGHT_BOTTOM );
			this.resizer.addPosition( this.resizeIconDummy, ResizeAlign.RIGHT_BOTTOM );
			this.resizer.addPosition( this.btnCapture, ResizeAlign.CENTER_MIDDEL );
			this.resizer.addPosition( this.btnCaptureFull, ResizeAlign.CENTER_MIDDEL );
			//addition guideline
			this.resizer.addScale( this.guideline, ResizeScale.XY );
			
			// calculate dummy dragging margin.
			this.resizeDummyMargin = new Point( this.width - this.resizeIconDummy.x, this.height - this.resizeIconDummy.y );
			
			const BOUND_MIN: Point = new Point( 180, 240 );
			const BOUND_MAX: Point = new Point( 800, 600 );
			
			this.resizeBound = new Rectangle( 
																BOUND_MIN.x - this.resizeIconDummy.width, 		// x
																BOUND_MIN.y - this.resizeIconDummy.height, 	// y
																BOUND_MAX.x - BOUND_MIN.x, 						// width
																BOUND_MAX.y - BOUND_MIN.y							// height
															);
			
			this.resizeIconDummy.addEventListener( MouseEvent.MOUSE_DOWN, resizeStart );
		}
		
		override public function set width( value: Number ): void
		{
			this.resizer.resize( int( value ), this.height );
		}
		
		override public function set height( value: Number ): void
		{
			this.resizer.resize( this.width, int( value ) );
		}
		
		/**
		 * Initialize button listeners. 
		 */		
		private function initButtons(): void
		{
			this.btnCapture.addEventListener( MouseEvent.CLICK, captureListener );
			this.btnCaptureFull.addEventListener( MouseEvent.CLICK, captureFullListener );
		}
		
		public function get region(): Rectangle
		{
			return this.border.getBounds( this._parent );
		}
		
		private function captureListener( e: Event ): void
		{
			this.dispatchEvent( new CaptureEvent( CaptureEvent.CAPTURE_REGION ) );
		}
		
		private function captureFullListener( e: Event ): void
		{
			this.dispatchEvent( new CaptureEvent( CaptureEvent.CAPTURE_FULL ) );
		}
	}
}